package com.ruoyi.websocket.handler;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.websocket.domain.ReceiveMessage;
import com.ruoyi.websocket.domain.WebSocketMessage;
import com.ruoyi.websocket.service.WebSocketMessageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.socket.*;

import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;

/**
 * WebSocket消息处理器
 * 
 * @author ruoyi
 */
public class MessageWebSocketHandler implements WebSocketHandler {

    @Autowired
    private WebSocketMessageService webSocketMessageService;

    private final ObjectMapper objectMapper = new ObjectMapper();
    
    // 存储用户会话，key为userId，value为WebSocketSession
    private static final ConcurrentHashMap<Long, WebSocketSession> USER_SESSIONS = new ConcurrentHashMap<>();

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        // 连接建立后，将用户会话存储
        Long userId = (Long) session.getAttributes().get("userId");
        String username = (String) session.getAttributes().get("username");
        
        if (userId != null) {
            USER_SESSIONS.put(userId, session);
            System.out.println("用户 " + username + "（ID:" + userId + "）建立WebSocket连接，当前在线用户数：" + USER_SESSIONS.size());
            
            // 发送连接成功消息
            WebSocketMessage welcomeMsg = new WebSocketMessage("message", "连接成功，欢迎 " + username + "！");
            sendMessageToUser(userId, welcomeMsg);
        }
    }

    @Override
    public void handleMessage(WebSocketSession session, org.springframework.web.socket.WebSocketMessage<?> message) throws Exception {
        try {
            String payload = message.getPayload().toString();
            
            // 解析消息
            ReceiveMessage receiveMessage = objectMapper.readValue(payload, ReceiveMessage.class);
            Long userId = (Long) session.getAttributes().get("userId");
            
            // 根据消息类型处理
            switch (receiveMessage.getType()) {
                case "heartbeat":
                    // 心跳消息，回复pong（不记录日志，避免刷屏）
                    WebSocketMessage pong = new WebSocketMessage("heartbeat", "pong");
                    session.sendMessage(new TextMessage(objectMapper.writeValueAsString(pong)));
                    return; // 直接返回，不继续处理
                    
                case "like":
                    // 点赞通知
                    System.out.println("收到点赞消息：" + payload);
                    webSocketMessageService.handleLikeMessage(receiveMessage, userId);
                    break;
                    
                case "comment":
                    // 评论通知
                    System.out.println("收到评论消息：" + payload);
                    webSocketMessageService.handleCommentMessage(receiveMessage, userId);
                    break;
                    
                case "follow":
                    // 关注通知
                    System.out.println("收到关注消息：" + payload);
                    webSocketMessageService.handleFollowMessage(receiveMessage, userId);
                    break;
                    
                case "message":
                    // 一般消息
                    System.out.println("收到一般消息：" + payload);
                    webSocketMessageService.handleGeneralMessage(receiveMessage, userId);
                    break;
                    
                default:
                    System.out.println("收到未知消息类型：" + receiveMessage.getType() + "，内容：" + payload);
            }
            
        } catch (Exception e) {
            System.err.println("处理WebSocket消息失败：" + e.getMessage());
            e.printStackTrace();
        }
    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        Long userId = (Long) session.getAttributes().get("userId");
        String username = (String) session.getAttributes().get("username");
        System.err.println("用户 " + username + "（ID:" + userId + "）WebSocket传输错误：" + exception.getMessage());
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
        // 连接关闭后，移除用户会话
        Long userId = (Long) session.getAttributes().get("userId");
        String username = (String) session.getAttributes().get("username");
        
        if (userId != null) {
            USER_SESSIONS.remove(userId);
            System.out.println("用户 " + username + "（ID:" + userId + "）断开WebSocket连接，当前在线用户数：" + USER_SESSIONS.size());
        }
    }

    @Override
    public boolean supportsPartialMessages() {
        return false;
    }

    /**
     * 向指定用户发送消息
     * 
     * @param userId 用户ID
     * @param message 消息内容
     */
    public static void sendMessageToUser(Long userId, WebSocketMessage message) {
        WebSocketSession session = USER_SESSIONS.get(userId);
        if (session != null && session.isOpen()) {
            try {
                ObjectMapper mapper = new ObjectMapper();
                String jsonMessage = mapper.writeValueAsString(message);
                session.sendMessage(new TextMessage(jsonMessage));
                System.out.println("向用户 " + userId + " 发送消息：" + jsonMessage);
            } catch (IOException e) {
                System.err.println("向用户 " + userId + " 发送消息失败：" + e.getMessage());
            }
        } else {
            System.out.println("用户 " + userId + " 不在线，无法发送消息");
        }
    }

    /**
     * 广播消息给所有在线用户
     * 
     * @param message 消息内容
     */
    public static void broadcastMessage(WebSocketMessage message) {
        ObjectMapper mapper = new ObjectMapper();
        try {
            String jsonMessage = mapper.writeValueAsString(message);
            for (WebSocketSession session : USER_SESSIONS.values()) {
                if (session.isOpen()) {
                    session.sendMessage(new TextMessage(jsonMessage));
                }
            }
            System.out.println("广播消息给 " + USER_SESSIONS.size() + " 个在线用户：" + jsonMessage);
        } catch (IOException e) {
            System.err.println("广播消息失败：" + e.getMessage());
        }
    }

    /**
     * 获取在线用户数
     */
    public static int getOnlineUserCount() {
        return USER_SESSIONS.size();
    }

    /**
     * 检查用户是否在线
     */
    public static boolean isUserOnline(Long userId) {
        WebSocketSession session = USER_SESSIONS.get(userId);
        return session != null && session.isOpen();
    }
}
